package cn.xd.core.design.chain;

import cn.xd.common.exception.BizException;

import java.util.Objects;

@FunctionalInterface
public interface Chain<T extends ChainRequest, R extends ChainResponse> {

    /**
     * 处理
     *
     * @param t
     * @param r
     * @throws BizException 业务异常
     */
    void accept(T t, R r) throws BizException;

    /**
     * 链式调用
     *
     * @param after
     * @return
     * @throws BizException 业务异常
     */
    default Chain<T, R> andThen(Chain<T, R> after) throws BizException {
        Objects.requireNonNull(after);
        return (l, r) -> {
            accept(l, r);
            if (!r.isStop()) {
                after.accept(l, r);
            }
        };
    }

    /**
     * 结束操作，表示必定会被执行
     *
     * @param after
     * @return
     */
    default Chain<T, R> end(Chain<T, R> after) throws BizException {
        Objects.requireNonNull(after);
        return (l, r) -> {
            try {
                accept(l, r);
                after.accept(l, r);
            } catch (BizException e) {
                after.accept(l, r);
                throw e;
            }

        };
    }

}
